package com.xy.tool.webmvc.op;

import com.xy.lang.domain.OrderConstant;
import com.xy.lang.util.CalendarUtils;
import com.xy.tool.util.LogUtils;
import com.xy.tool.webmvc.util.RequestUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.util.StopWatch;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by zsp on 2018/11/21.
 */
@Slf4j
@Order(OrderConstant.FIRST)
@Aspect
public class AccessLogAspect {

    @Pointcut("execution(* com.xy..*.controller..*.*(..))")
    public void access() {

    }

    @Around("access()")
    public Object invoke(ProceedingJoinPoint pjp) throws Throwable {
        if(!log.isDebugEnabled()) {
            return pjp.proceed();
        }

        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        LocalDateTime start = LocalDateTime.now();

        Object obj = pjp.proceed();

        Object bean = pjp.getTarget();
        Class<?> clazz = bean.getClass();
        MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
        Method method = methodSignature.getMethod();
        Object[] arguments = pjp.getArgs();
        List<String> argumentList = new ArrayList<>();
        if(arguments != null && arguments.length > 0) {
            for(Object argument : arguments) {
                if(argument == null
                        || argument instanceof ServletRequest
                        || argument instanceof ServletResponse) {
                    continue;
                }
                argumentList.add(argument.toString());
            }
        }
        HttpServletRequest request = RequestUtils.getRequest();
        String uri = (request==null ? "" : request.getRequestURI());
        stopWatch.stop();
        LogUtils.debug(log,
                "url: {}, class: {}, method: {}, startAt: {}, cost: {}, data: {}",
                uri,
                clazz.getName(),
                method.getName(),
                CalendarUtils.format(start),
                stopWatch.getLastTaskTimeMillis(),
                argumentList);

        return obj;
    }

}
